import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter_baselib/lib.dart';
import 'package:flutter_baselib_example/net/http_const.dart';
import 'package:flutter_baselib_example/net/http_urls.dart';
import 'package:flutter_baselib_example/net/interceptors/header_interceptor.dart';
import 'package:flutter_baselib_example/net/util/http_json_utils.dart';

///@date:  2021/2/26 14:01
///@author:  lixu
///@description: http相关配置
class HttpConfigImpl implements IHttpConfig {
  String _tag = 'HttpConfigImpl';

  ///配置通用的http请求选项[BaseOptions]
  @override
  BaseOptions configBaseOptions() {
    BaseOptions options = BaseOptions(
      baseUrl: HttpUrls.httpHost,
      connectTimeout: HttpConst.httpTimeOut,
      receiveTimeout: HttpConst.httpTimeOut,
      sendTimeout: HttpConst.httpTimeOut,
      contentType: XApi.contentTypeJson,
      method: XApi.methodPost,
      responseType: ResponseType.json,
    );
    return options;
  }

  ///返回http成功的响应码
  @override
  String configHttpResultSuccessCode() {
    return HttpConst.httpResultSuccess.toString();
  }

  ///配置https
  @override
  bool configHttps(X509Certificate cert, String host, int port) {
    return true;
  }

  @override
  List<Interceptor> configInterceptors() {
    List<Interceptor> interceptors = [];
    interceptors.add(HeaderInterceptor());
    return interceptors;
  }

  ///是否自动添加[LogInterceptors]拦截器,打印http请求相关的日志
  ///拦截器队列的执行顺序是FIFO，先添加的拦截器先执行
  @override
  bool configLogEnable() {
    return true;
  }

  ///每个http请求前回调该方法获取host
  ///[url] 当前正在请求的接口url
  @override
  String getHttpHost(String url) {
    return HttpUrls.httpHost;
  }

  ///http请求失败时会回调该方法，判断token是否失效
  ///[errorBean] 请求失败对象
  @override
  bool isHttpRespTokenError(HttpErrorBean errorBean) {
    return HttpConst.sysTokenError.toString() == errorBean.code || HttpConst.sysTokenExpired.toString() == errorBean.code;
  }

  ///token失效时回调该方法
  ///[errorBean] 请求失败对象
  @override
  void onTokenErrorCallback(HttpErrorBean errorBean) {
    ToastUtils.show("Token 失效：${errorBean.toString()}", isShowLong: true);

    ///TODO 实现token失效的业务逻辑
  }

  ///将http响应的json解析成对象
  ///[url] 当前请求url
  ///[jsonData] http响应完整json
  ///[isRespListData] 响应数据是否是List格式
  @override
  HttpResultBean<T> parseJsonToObject<T>(String url, Map<String, dynamic> jsonData, bool isRespListData) {
    ///TODO 参考下面代码逻辑，根据业务修改代码解析json为object
    return HttpJsonUtils.parseJsonToObject<T>(url, jsonData, isRespListData);
  }

  ///保存http请求时显示loadingDialog对应的context对象
  Map<int, BuildContext> loadingDialogContextMap = {};

  ///http请求时显示加载框：isShowLoading为true时，会回调该方法
  ///[tag] 当前请求对应的tag，唯一
  ///[cancelToken] 用于加载框关闭时取消http请求
  ///[loadingText] 加载提示提示
  ///[isCancelableDialog] 请求过程中能否关闭加载框,默认false
  @override
  void showLoading(int tag, CancelToken cancelToken, String loadingText, bool isCancelableDialog) {
    LogUtils.i(_tag, 'showLoading tag:$tag  loadingText:$loadingText');

    showDialog(
      context: BaseLibPlugin.context,
      barrierColor: Colors.transparent,
      barrierDismissible: false,
      builder: (BuildContext dialogContext) {
        loadingDialogContextMap.putIfAbsent(tag, () => dialogContext);

        ///TODO 可以参考HttpLoadingDialog类自定义dialog样式
        return HttpLoadingDialog(loadingText, isCancelableDialog, cancelToken);
      },
    );
  }

  ///http请求完成，关闭加载框：isShowLoading为true时，会回调该方法
  ///[tag]当前请求对应的tag，唯一
  @override
  void hideLoading(int tag) {
    BuildContext context = loadingDialogContextMap[tag];
    LogUtils.i(_tag, 'hideLoading tag:$tag  context is null:${context == null}');
    if (context != null) {
      loadingDialogContextMap.remove(tag);
      Navigator.of(context).pop();
    }
  }
}
